﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using DomoBCI.Core.Comunication;
using System.Net.Sockets;
using System.Net;
using System.Text;


namespace DomoBCI.Core.Comunication
{
    public class BCIDriver
    {
        Boolean isRunning = false;

        private Socket server;
        private IPEndPoint ip;
        protected BCIMessage bci;

        // costruttore
        public BCIDriver()
        {

        }

        public string doWork(){

            // 1) apro un socket sulla porta 3001
            ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3001);
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                server.Connect(ip);
            }
            catch (SocketException)
            {
                return null;
            }

            isRunning = true;

            // 2) invio REQUEST_PARAMS
            bci = new BCIMessage();
            int[] nullo = new int[16];
            byte[] sendb = new byte[76];
            byte[] buffer = new byte[4];

            bci.message = bci.ComposeMessage(DomoBCI.Core.Comunication.BCIMessage.REQUEST_PARAMS, 0, nullo, 0);
            sendb = bci2.utils.utils.BCIMessageToByte(bci.message);
            server.Send(sendb);
            // 3) richiesta start

           bci = new BCIMessage();
           nullo = new int[16];
           sendb = new byte[76];
           buffer = new byte[4];

           bci.message = bci.ComposeMessage(DomoBCI.Core.Comunication.BCIMessage.START_ACQ, 0, nullo, 0);
           sendb = bci2.utils.utils.BCIMessageToByte(bci.message);
           server.Send(sendb);

           // attesa risposta: CONNECTION_COMPLETED
           byte[] data = new byte[1024];
           int bytesReceived;
           string str = "ads";
           while (str[0] != 103)
           {

               bytesReceived = server.Receive(data, data.Length, SocketFlags.None);
               str = Encoding.UTF8.GetString(data, 0, data.Length);
               
          }

                       
                   // 5) event handler, ricezione + gestione comandi
               /*    while (!_shouldStop)
                   {
                            // ricezione
                           data = new byte[1024];

                           bytesReceived = server.Receive(data, 0, data.Length - 0, SocketFlags.None);

                           foreach (byte b in data)
                               Console.Write(b);
                           str = Encoding.UTF8.GetString(data, 0, data.Length);

                           // controllo il kind
                           // se è 301 (CLASSIFICATION) ho una direzione, invece se è 302 ho i FEEDBACK

                           // gestione CLASSIFICATION

                
                           // gestione FEEDBACK - valori presenti nel buffer

                           
                   }
                   Console.WriteLine("worker thread: terminating gracefully.");  */
           return str;
        }

        public void SendMessage() {
            bci = new BCIMessage();
            int[] nullo = new int[16];
            byte[] sendb = new byte[76];
            byte[] buffer = new byte[4];


            bci.message = bci.ComposeMessage(DomoBCI.Core.Comunication.BCIMessage.GRAPH_TRIG, 0, nullo, 0);
            sendb = bci2.utils.utils.BCIMessageToByte(bci.message);
            if (server.Connected)
            {
                server.Send(sendb);
            }
        }


        // for Thread
        public void RequestStop()
        {
            //_shouldStop = true;
            
            // mi disconnetto
            server.Close();
        }
        // Volatile is used as hint to the compiler that this data
        // member will be accessed by multiple threads.
        private volatile bool _shouldStop;
          
    }
}
